from simpy import Environment

from osc01.resource.MonitoredFilterStore import MonitoredFilterStore
from osc01.resource.Resources import ResourceUtil
from osc01.resource.stakeholders import ConstructionSite
from osc01.utils import global_var
from osc01.utils.cpm_util import get_schedule
from osc01.utils.random_util import RandomUtil

global_var.init()
global_var.set_value('STOCHASTIC_MODE', True)

activities, prj_start_date = get_schedule()
env = Environment()

# storage_yard = ResourceUtil.get_storage_yard(env, capacity=200)
storage_yard = MonitoredFilterStore(env, capacity=200)
# workers = ResourceUtil.get_workers(env, capacity=9)
assembly_worker_teams = ResourceUtil.get_stations(env, capacity=1)
grout_worker_teams = ResourceUtil.get_stations(env, capacity=1)
grout_gears = ResourceUtil.get_stations(env, capacity=1)

construction_site1 = ConstructionSite(env=env, name='Site1',
                                      storage_yard=storage_yard,
                                      worker_teams=assembly_worker_teams,
                                      grout_gears=grout_gears,
                                      crane_num=1,
                                      activities=activities)
#
random_util = RandomUtil(5, 24, 24)
# act_duration of walls of two types
act_duration = []
durations = random_util.get_sf_erection_durations()
act_duration.extend(durations)
durations = random_util.get_in_wall_erection_durations()
act_duration.extend(durations)
print(act_duration)
act_delivery_delay = random_util.get_component_delivery_delays()
print(act_delivery_delay)

# set act_duration, act_delivery
index = 0
for activity in activities:
    activity.skd_delivery_time = activity.es
    activity.construction_site = construction_site1
    activity.completion_event = env.event()
    activity.component_delivered_event = env.event()
    # actual
    activity.act_duration = round(act_duration[index], 2)
    activity.act_delivery_time = activity.skd_delivery_time + max(0, round(act_delivery_delay[index], 2))
    index += 1
    # print(activity.name, activity.es)

for activity in activities:
    print(activity.name, round(activity.es, 2), activity.duration,  # round(activity.act_erection_start, 2),
          activity.act_duration,
          round(activity.skd_delivery_time, 2), round(activity.act_delivery_time, 2))

# the act_delivery_time has been preset, no need to process.
var_global_in_func = 1
for activity in activities:
    # if counter < 97:
    if var_global_in_func < 97:
        env.process(activity.transport())
        var_global_in_func += 1

var_global_in_func = 1
for activity in activities:
    # if counter < 97:
    if var_global_in_func < 97:
        env.process(activity.act())
        var_global_in_func += 1

env.run(until=2000)

print(env.now, construction_site1)
for activity in activities:
    print(activity.name, round(activity.es, 2), activity.duration, round(activity.act_erection_start, 2),
          activity.act_duration,
          round(activity.skd_delivery_time, 2), round(activity.act_delivery_time, 2))
